home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-04 | 6.8 KB | 163 lines | [TEXT/KAHL] |
- Macintosh Directory Scanning Routines
-
- By George T. Talbot
-
- After programming on Sun workstations, I learned the usefulness of the "dirent" routines.
- These routines provide an easy, portable method of reading directory contents. So, I
- implemented these routines on the Macintosh and tried to make them as close as possible
- to the UNIX routines. Note that in this document I use the word "directory" instead of
- the word "folder". Shoot me.
-
- A couple of important notes before we begin:
- Due to limitations in the Macintosh File System, all pathnames in this package are
- limited to 255 characters (MAXPATHLEN). If you want longer pathnames, you'll have
- to break the pathnames up yourself.
-
- Any errors generated by these routines will be put in the global variable "dd_errno".
-
- Here they are:
-
- DIR *opendir(char *dirname);
-
- This routine takes a Macintosh-style pathname and will open that directory and
- make it ready for reading. You may also pass in nil instead of a pointer to
- a string to open the current working directory.
-
- If you've really got to use UNIX-style pathnames, you can set the variable
- "dd_xform_seps" to true and "/" will be transformed to ":" by this routine. Note
- that if the individual directory names have "/" in them, that this routine will
- not be able to open any path with that directory name in them while this variable
- is true. The default value of this variable is false.
-
- It is important to remember that the pathname, whatever separator is used, is a
- Macintosh pathname and not a UNIX pathname. This is important for relative pathnames.
-
- ".:", "..:" & "≈:" are supported if the pathname starts with
- these strings. ".:" means "relative to current directory" and "..:" & "≈:" mean
- relative to the current directory's parent directory.
-
- This routine will return a pointer to a DIR structure:
-
- typedef struct __dirdesc {
- /* PRIVATE FIELDS. Use the fields & defines below PUBLIC */
- ...
-
- /* PUBLIC */
- long dd_fd; /* file descriptor (dirID) of this dir */
-
- #define dd_parent ... /* dirID of parent */
- #define dd_bsize ... /* amount of entries read at a time (always 1) */
- #define dd_size ... /* amount of valid data in buffer (ignore) */
- #define dd_loc ... /* Don't remember what this field means */
- #define dd_name ... /* Directory name (C string) */
- #define dd_volume ... /* vRefNum where this is located */
-
- long dd_numents; /* Number of files/directories in this directory */
- } DIR;
-
- I do have one significant departure from the UNIX way of doing things. The field
- "dd_fd" in UNIX will identify a particular folder, no matter what filesystem the
- directory is in. On the Mac, you'll require that field and dd_volume to identify
- the directory. Most programs won't have to look at those fields.
-
- The default separator is held in the variable "dd_separator". This variable is a
- pointer to a C string. You could probably be compatible with A/UX by setting this
- variable to "/" and dd_xform_seps to false, but I haven't tried this.
-
- struct dirent *readdir(DIR *dirp);
-
- This routine reads the next directory entry in the directory (or the first one, if
- opendir() has just been called). This routine will return nil and set dd_errno to
- noErr when the end of the directory is reached. In case of error, it will also
- return nil, but dd_errno will be set to some Mac error code.
-
- The structure this routine returns a pointer to looks like this:
-
- struct dirent {
- /* PRIVATE FIELDS. Use fields after PUBLIC */
- ...
-
- /* PUBLIC. */
- long d_off; /* index (to seekdir()) of this entry */
- long d_fileno; /* File number (dirID) of this entry */
- #define d_parent ... /* File number (dirID) of parent */
- #define d_reclen ... /* Size of this record */
- #define d_namelen ... /* Length of the name */
- #define d_name ... /* Name */
- #define d_volume ... /* vRefNum where this is located */
- };
-
- The pointer you get to this structure is valid only while the directory is open. When
- the directory is closed with closedir(), this pointer goes away.
-
- extern int closedir(DIR *dirp);
-
- This routine closes a directory opened with opendir(). It will return -1 in case of
- error and set dd_errno. If you do get an error from this routine, get ready to crash
- because the only errors that could happen are Memory Manager errors.
-
- extern void seekdir(DIR *dirp, long loc);
-
- In an open directory, this package indexes directory entries from 0 to the number
- of entries in the directory-1 (0..n-1). This function will seek to a specific
- directory entry. It's intended to be used before a call to readdir() or telldir().
-
- extern long telldir(DIR *dirp);
-
- This function will return the index of the next directory entry to be read from
- the open directory specified by dirp, or -1 if the last entry has just been read.
-
- extern void rewinddir(DIR *dirp);
-
- This is equivalent to seekdir(dirp, 0). It will seek to the first entry in the
- open directory.
-
- These routines are not part of a standard dirent package, but are VERY useful,
- nonetheless:
-
- char *getwd(char *path);
-
- This routine will get you a fully qualified pathname to the current working directory.
- You'll pass in a pointer to a buffer of MAXPATHLEN characters. If the routine is
- successful, it will return the pointer to the buffer you passed in. If it fails,
- it will return nil and set dd_errno.
-
- extern int chdir(char *path);
-
- This routine will change the current working directory, given a path with the same
- constraints as opendir(). It will return 0 on success, and will set dd_errno and
- return -1 on failure.
-
- extern char *pathdir(DIR *dirp, char *path);
-
- Given a pointer to an open directory, this routine will generate a fully qualified
- path name to that directory. You'll pass in a pointer to a buffer of MAXPATHLEN
- characters. If the routine is successful, it will return the pointer to the buffer
- you passed in. If it fails, it will return nil and set dd_errno.
-
- That's about it. This code may be used freely with the following caveats:
-
- 1) If you distribute source code with this code in it, distribute this documentation
- file also.
-
- 2) If you include this code in a commercial product, send me a copy of the product
- and make me a registered user. If you feel that this is unfair, then send me
- $10 U.S. and tell me why. If you can't abide by this clause, then don't use this
- code in your commercial product.
-
- 3) I'd like to see how far this thing goes, so send me a postcard if you use it and
- find it useful.
-
- 4) If you find bugs in this code, let me know. If you make any improvements, please
- send me source so I can learn something.
-
- This software was created with Think C 5.0.4 and tested on a Macintosh Centris 610 running
- System 7. It should work with earlier Systems, but it probably won't work (and in fact
- will probably crash) without HFS.
-
- George T. Talbot
- 24 Judy Ave.
- Franklinville, NJ 08322
-
- <ugtalbot@mcs.drexel.edu>
-